%     VIRTUAL LAMINATE - программа для получения эффективных свойств слоистых пластин
%     Copyright (C) 2020  Михаил Козлов
%     Сайт проекта: <http://www.fastenerdoctor.ru/>
%     Адрес электронной почты для связи с разработчиком:
%     <doctor.fastener@gmail.com>
% 
%     Эта программа является свободным программным обеспечением: Вы можете
%     распространять ее и/или изменять, соблюдая условия Универсальной общественной
%     лицензии GNU, опубликованной Фондом свободного программного обеспечения,
%     либо редакции 3, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
% 
%     Эта программа распространяется в надежде на то, что она окажется полезной,
%     но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая даже подразумеваемую гарантию ТОВАРНОЙ ПРИГОДНОСТИ,
%     либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Универсальной общественной
%     лицензией GNU для получения более подробной информации.
% 
%     Вы должны были получить копию Универсальной общественной лицензии GNU
%     вместе с этой программой. Если Вы ее не получили, то перейдите по адресу:
%     <http://www.gnu.org/licenses/>.
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <https://www.gnu.org/licenses/>.

function Write_Input_Mesh(Work_Directory, NODES, ELEMENTS, Ply_Elements, Materials, Stacking, Element_Order)

global ErrCode;

node_coord_format = '%.12e';
orientation_format = '%.12e';
mat_prop_format = '%.12e';

fprintf (1, 'Создание .inp файла с сеткой...                         ');

Part_Name = 'LAMINATE_RVE';
Job_Name = 'Virtual_Laminate_RVE_mesh';
Model_Name = 'Virtual_Laminate_RVE_mesh';

% Проверка нумерации узлов
for i=1:size(NODES,1)
    if (NODES(i,1) ~= i)
        fprintf (1, '\nОшибка функции Write_Input_Mesh: некорректная нумерация узлов!\n');
        ErrCode = -1;
        return;
    end
end

% Проверка нумерации элементов
for i=1:size(ELEMENTS,1)
    if (ELEMENTS(i,1) ~= i)
        fprintf (1, '\nОшибка функции Write_Input_Mesh: некорректная нумерация элементов!\n');
        ErrCode = -1;
        return;
    end
end

File_name = Job_Name;
File_path = [Work_Directory '\' File_name '.inp'];

Fout = fopen(File_path, 'wt');

if (Fout < 0)
    fprintf (1, '\nОшибка функции Write_Input_Mesh: не удалось открыть для записи файл [%s] !\n', File_path);
    ErrCode = -1;
    return;
end

fprintf (Fout, '*Heading\n');

fprintf (Fout, '** Job name: %s Model name: %s\n', Job_Name, Model_Name);
fprintf (Fout, '** Generated by: Virtual_Laminate\n');

fprintf (Fout, '*Preprint, echo=NO, model=NO, history=NO, contact=NO\n');

fprintf (Fout, '**\n');
fprintf (Fout, '** PARTS\n');
fprintf (Fout, '**\n');

fprintf (Fout, '*Part, name=%s\n', Part_Name);

fprintf (Fout, '*Node\n');

for i=1:size(NODES, 1)
    fprintf (Fout, ['%i, ' node_coord_format ', ' node_coord_format ', ' node_coord_format '\n'], NODES(i,1), NODES(i,2), NODES(i,3), NODES(i,4));
end

switch Element_Order
    
    case 'LINEAR'
        
        fprintf (Fout, '*Element, type=C3D8I\n');

        for i=1:size(ELEMENTS,1)
            fprintf (Fout, '%i, %i, %i, %i, %i, %i, %i, %i, %i\n', ELEMENTS(i,1), ELEMENTS(i,5), ELEMENTS(i,6), ELEMENTS(i,7), ...
                                                                   ELEMENTS(i,8), ELEMENTS(i,9), ELEMENTS(i,10), ELEMENTS(i,11), ...
                                                                   ELEMENTS(i,12));
        end
        
    case 'QUADRATIC'
        
        fprintf (Fout, '*Element, type=C3D20R\n');

        for i=1:size(ELEMENTS,1)
            fprintf (Fout, '%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i,\n', ELEMENTS(i,1), ELEMENTS(i,5), ELEMENTS(i,6), ELEMENTS(i,7), ...
                                                                                               ELEMENTS(i,8), ELEMENTS(i,9), ELEMENTS(i,10), ELEMENTS(i,11), ...
                                                                                               ELEMENTS(i,12), ELEMENTS(i,13), ELEMENTS(i,14), ELEMENTS(i,15), ...
                                                                                               ELEMENTS(i,16), ELEMENTS(i,17), ELEMENTS(i,18), ELEMENTS(i,19));
            fprintf (Fout, '   %i, %i, %i, %i, %i\n', ELEMENTS(i,20), ELEMENTS(i,21), ELEMENTS(i,22), ELEMENTS(i,23), ELEMENTS(i,24));
        end
    
end

fprintf (Fout, '*Nset, nset=ALL_NODES, generate\n');
fprintf (Fout, ' %i, %i, 1\n', 1, NODES(size(NODES,1),1));

fprintf (Fout, '*Elset, elset=ALL_ELEMENTS, generate\n');
fprintf (Fout, ' %i, %i, 1\n', 1, ELEMENTS(size(ELEMENTS,1),1));

N_digits = numel(num2str(Stacking(size(Stacking,1),1)));

format_line = ['*Elset, elset=Ply_%.' sprintf('%i', N_digits) 'i\n'];

N_previous_items = 0;

for i=1:size(Stacking,1)
        
    fprintf (Fout, format_line, Stacking(i,1));
    
    Write_Set(Fout, ELEMENTS(N_previous_items + 1 : N_previous_items + Ply_Elements(i), 1));
    
    N_previous_items = N_previous_items + Ply_Elements(i);
    
end

format_line = ['*Orientation, name=Ori_Coord_%.' sprintf('%i', N_digits) 'i\n'];

format_line_2 = [orientation_format ', ' orientation_format ', ' orientation_format ', ' orientation_format ', ' orientation_format ', ' orientation_format ', ' orientation_format ', ' orientation_format ', ' orientation_format '\n'];

Origin_High = 0;

for i=1:size(Stacking,1)
    
    fprintf (Fout, format_line, Stacking(i,1));
    
    fprintf (Fout, format_line_2,  cosd(Stacking(i,2)), sind(Stacking(i,2)), Origin_High + Materials{Stacking(i,3)}.t/2, ...
                                  -sind(Stacking(i,2)), cosd(Stacking(i,2)), Origin_High + Materials{Stacking(i,3)}.t/2, ...
                                                                       0, 0, Origin_High + Materials{Stacking(i,3)}.t/2);
    fprintf (Fout, '3, 0.\n');
    
    Origin_High = Origin_High + Materials{Stacking(i,3)}.t;
    
end

format_line = ['** Section: Section_Ply_%.' sprintf('%i', N_digits) 'i\n'];

format_line_2 = ['*Solid Section, elset=Ply_%.' sprintf('%i', N_digits) 'i, orientation=Ori_Coord_%.' sprintf('%i', N_digits) 'i, material=Material_%i\n'];

for i=1:size(Stacking,1)
    
    fprintf (Fout, format_line, Stacking(i,1));
    
    fprintf (Fout, format_line_2, Stacking(i,1), Stacking(i,1), Stacking(i,3));
    
    fprintf (Fout, ',\n');
    
end

fprintf (Fout, '*End Part\n');

fprintf (Fout, '**\n');
fprintf (Fout, '** ASSEMBLY\n');
fprintf (Fout, '**\n');

fprintf (Fout, '*Assembly, name=Assembly\n');
fprintf (Fout, '**\n');
fprintf (Fout, '*Instance, name=%s-1, part=%s\n', Part_Name, Part_Name);
fprintf (Fout, '*End Instance\n');
fprintf (Fout, '**\n');
fprintf (Fout, '*End Assembly\n');

fprintf (Fout, '**\n');
fprintf (Fout, '** MATERIALS\n');
fprintf (Fout, '**\n');

Mat_Numbers = unique(Stacking(:,3));

format_line = [mat_prop_format ', ' mat_prop_format ', ' mat_prop_format ', ' mat_prop_format ', ' mat_prop_format ', ' mat_prop_format ', ' mat_prop_format ', ' mat_prop_format '\n'];

for i=1:numel(Mat_Numbers)
    
    fprintf (Fout, '*Material, name=Material_%i\n', Mat_Numbers(i));
    fprintf (Fout, '*Elastic, type=ENGINEERING CONSTANTS\n');
    fprintf (Fout, format_line, Materials{Mat_Numbers(i)}.E1, Materials{Mat_Numbers(i)}.E2, Materials{Mat_Numbers(i)}.E3, ...
                                Materials{Mat_Numbers(i)}.nu12, Materials{Mat_Numbers(i)}.nu13, Materials{Mat_Numbers(i)}.nu23, ...
                                Materials{Mat_Numbers(i)}.G12, Materials{Mat_Numbers(i)}.G13);
    fprintf (Fout, [mat_prop_format ',\n'], Materials{Mat_Numbers(i)}.G23);
    fprintf (Fout, '*Expansion, type=ORTHO\n');
    fprintf (Fout, [mat_prop_format ', ' mat_prop_format ', ' mat_prop_format '\n'], Materials{Mat_Numbers(i)}.alpha11, Materials{Mat_Numbers(i)}.alpha22, Materials{Mat_Numbers(i)}.alpha33);

end

fclose(Fout);

fprintf (1, 'OK!\n');

% Сообщение об успешном создании файла с результатами
fprintf (1, '\n    Файл [%s] создан успешно!\n', File_path);
